package temp;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Hashtable;

public class MediaClient {
	
	private Socket clientSocket;
	private ObjectInputStream inputStream;
	private ObjectOutputStream outputStream;
	
	private Hashtable<String,NewFormat> filesInServer;
		

	private int clientPort;
	
	public MediaClient(String serverIP,int clientPort) {
		try {
			clientSocket = new Socket(InetAddress.getByName(serverIP),Constants.CENTRAL_SEVER_TCP_PORT);
	        outputStream = new ObjectOutputStream(clientSocket.getOutputStream());
			inputStream = new ObjectInputStream(clientSocket.getInputStream());	        
	        this.clientPort = clientPort;
	        
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	private void sendListRequest(){
		try {
			Message listMessage = new Message("list",MESSAGE_TYPE.LIST,null);
			outputStream.writeObject(listMessage);
			outputStream.flush();
			
			Object response = inputStream.readObject();
			
			if (response instanceof Message) {
				Message responseMessage = (Message) response;
				
				if (responseMessage.getType() == MESSAGE_TYPE.OK) {
					response = responseMessage.getObject();
					if (response instanceof Hashtable) {
						filesInServer = (Hashtable<String, NewFormat>) response;
					}
				}
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public Enumeration<String> getFileListInServer(){
		sendListRequest();
		Enumeration<String> filesNames= this.filesInServer.keys();
		return filesNames;
	}
	
	public void sendGetRequest(String fileName){
		
		try {
			if (filesInServer != null) {
				if (filesInServer.containsKey(fileName)) {
					Message getMessage = new Message(fileName,MESSAGE_TYPE.GET,this.clientPort);//manda a porta
					outputStream.writeObject(getMessage);
					outputStream.flush();
				}
			}
			
			
			Object response = inputStream.readObject();
			
			if (response instanceof Message) {
				Message responseMessage = (Message) response;
				
				if (responseMessage.getType() == MESSAGE_TYPE.OK) {// o servidor vai comecar a reproduzir
					System.out.println(responseMessage.getMessage());
					startReceiverAndPlayer(fileName);
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void startReceiverAndPlayer(String fileName) {
		

		NewFormat format = filesInServer.get(fileName);
		
		double frameRate = format.getFrameRate();
        double frameSize = format.getFrameSize();
        double byteRate = frameRate*frameSize; 
        int payloadSizeInBytes = (int) (byteRate*(Constants.PAYLOAD_LENGTH_IN_MILISECONDS/1000.0));
		int bufferSize = payloadSizeInBytes * Constants.BUFFER_SIZE_IN_PACKETS;
		
		//responsavel por armazenar os dados
		MediaPacketReceiver mediaPacketReceiver = new MediaPacketReceiver(bufferSize,Constants.WINDOW_LENGTH_IN_PACKETS,payloadSizeInBytes);
		      
		ConnectionDescription connectionDescription = new ConnectionDescription(format,payloadSizeInBytes,this.clientPort);
		//reponsavel por ler do socket
		MediaReceiver mediaReceiver = new MediaReceiver(connectionDescription,mediaPacketReceiver);
		//responsavel por executar a midia
		MediaPlayer mediaPlayer = new MediaPlayer(mediaPacketReceiver,connectionDescription);
		
		Thread receiver = new Thread(mediaReceiver);
		receiver.start();
		
		Thread player = new Thread(mediaPlayer);
		player.start();
	}

	public static void main(String[] args) {
		MediaClient mediaClient = new MediaClient(Constants.CENTRAL_SEVER_IP,Constants.CLIENT_UDP_PORT);
		Enumeration<String> files = mediaClient.getFileListInServer();
		System.out.println("files in server");
		String filename = null;
		while(files.hasMoreElements()){
			filename = files.nextElement();
			System.out.println(filename);
		}
		System.out.println("------------xx--------------");
		mediaClient.sendGetRequest(filename);
	}

}
